package us.versus.them.b3ge.phyxside;

import flash.net.URLRequest;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.events.Event;

import phx.Vector;

class Worldly extends Sprite {
	var world : phx.World;
	var size : phx.Vector;
	var bob : phx.Body;
	var flipper:Flipper;
	var painter:Painter;

	public static var bobSize   = 30;

	// need to move away from this silliness
	var currentLoop : flash.events.Event -> Void;

	////

	public function new( flipper:Flipper ) {
		super();
		this.flipper = flipper;
   		this.painter = new Painter();
	}

	////

	public function flip( name:String ) {
		flipper.activate( name );
	}

	////////////////////////////////////////////////////////////////////////
	// OVERRIDE THESE

	public function activate() {
		this.listen();
		this.starterWorld();
	}

	public function deactivate() {
	}

	public function preCreateWorld() {
	}

	public function postCreateWorld() {
	}

	public function preWorldLoop( event:Event ) {}

	public function postWorldLoop( event:Event ) {}

	public function listenMore() {}

	public function bobTo( x : Float, y : Float ) {
		bob.x = x;
		bob.y = y;
	}

	public function goalTo( x : Float, y : Float ) {}

	////////////////////////////////////////////////////////////////////////

	////

	public function starterWorld() {
		this.createWorld();
	}

	public function createWorld() {
		bob = new phx.Body( 200, 250 );
		bob.addShape( new phx.Circle( bobSize, new phx.Vector( 0, 0 ) ) );

		this.preCreateWorld();

		var size = new phx.col.AABB( -1064,-1064, 1064,1064 );
		var bf = new phx.col.SortedList();
		world = new phx.World( size, bf );
		this.x = this.y = 0;
		world.addBody( bob );
		this.postCreateWorld();
	}

	public function addFloor( x : Float, y : Float, w : Float, h : Float ) {
		if ( w < 0 ) {
			x += w;
			w = -w;
		}
		if ( h < 0 ) {
			y += h;
			h = -h;
		}
		var floor = phx.Shape.makeBox( w, h, x, y );
		world.addStaticShape( floor );
		return floor;
	}

	public function addPolyFloor( points : Array< Vector > ) {
		world.addStaticShape( new phx.Polygon( points , new Vector( 0, 0 ) ) );
		points.reverse();
		world.addStaticShape( new phx.Polygon( points , new Vector( 0, 0 ) ) );
	}

	public function addBox( x : Float, y : Float, w : Float, h : Float ) {
		if ( w < 0 ) {
			x += w;
			w = -w;
		}
		if ( h < 0 ) {
			y += h;
			h = -h;
		}

		var body = new phx.Body( x, y );
		body.addShape( phx.Shape.makeBox( w, h ) );
		world.addBody( body );
		return body;
	}

	public function addPolyBox( points : Array< Vector > ) {
		var body = new phx.Body( 0, 0 );
		body.addShape( new phx.Polygon( points, new Vector( 0, 0 ) ) );
		world.addBody( body );
		return body;
	}

	public function useLoadingLoop() {
		currentLoop = loadingLoop;
	}

	public function useWorldLoop() {
		currentLoop = worldLoop;
	}

	public function worldSize( width : Float, height : Float ) {
        size = new Vector( width, height );
    }

	public function gravityTo( x : Float, y : Float ) {
		world.gravity = new phx.Vector( x, y );
	}

	// one loop to loop them all!
	public function loop( event : flash.events.Event ) {
		currentLoop( event );
	}

	public function loadingLoop( event : flash.events.Event ) {
		//trace( 'loading...' );
	}

	public function worldLoop( event : flash.events.Event ) {
		this.preWorldLoop( event );

		// update the world
		world.step(1,20);

		// this is where the drawing is done
		graphics.clear();
		painter.paint( this, world );
/*
		var fd = new phx.FlashDraw( graphics );
		fd.drawCircleRotation = true;
		fd.drawWorld( world );
*/
		this.postWorldLoop( event );
	}

	public function isFalling( body:phx.Body ) {
		return if ( null == body || null == body.island ) {
			false;
		} else { 
			!body.island.sleeping && Math.abs( body.v.y ) > 0.1;
		};
	}

	public function listen() {
		useLoadingLoop();
		this.addEventListener( Event.ENTER_FRAME, loop );
		this.listenMore();
	}


}
